package com.donger.business.upms.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.donger.business.upms.dto.UserDto;
import com.donger.business.upms.dto.UserInfo;
import com.donger.business.upms.entity.*;
import com.donger.business.upms.enums.YesOrNotEnum;
import com.donger.business.upms.mapper.SysPermissionMapper;
import com.donger.business.upms.mapper.SysRoleMapper;
import com.donger.business.upms.mapper.SysUserMapper;
import com.donger.business.upms.service.ISysAppService;
import com.donger.business.upms.service.ISysUserRoleService;
import com.donger.business.upms.service.ISysUserService;
import com.donger.common.core.exception.BizException;
import com.donger.common.data.service.Global;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.NotBlank;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

/**
 * <p>
 * 系统用户 服务实现类
 * </p>
 *
 * @author xyx
 * @since 2019-01-12
 */
@RequiredArgsConstructor
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

    private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();
    private final SysPermissionMapper sysPermissionMapper;
    private final ISysUserRoleService sysUserRoleService;
    private final SysRoleMapper sysRoleMapper;
    private final ISysAppService sysAppService;


    @Override
    public IPage getUserWithRolePage(Page page, Wrapper<SysUser> queryWrapper) {
        return baseMapper.getUserPage(page, queryWrapper);
    }

    /**
     * 获取用户详情
     * 带角色 和 权限
     *
     * @param sysUser
     * @return
     */
    @Override
    public UserInfo findUserInfo(SysUser sysUser) {
        if (sysUser == null) {
            return null;
        }
        UserInfo userInfo = new UserInfo();
        userInfo.setSysUser(sysUser);
        // 获取角色列表ID
        List<Long> roles = sysRoleMapper.listRolesByUserId(sysUser.getUserId())
                .stream()
                .map(SysRole::getRoleId)
                .collect(Collectors.toList());
        userInfo.setRoles(ArrayUtil.toArray(roles, Long.class));

        //  获取对应的apps 情况
        List<Dict> userAppDictList = CollectionUtil.newArrayList();

        //定义是否有默认激活的应用标志
        AtomicBoolean hasDefaultActive = new AtomicBoolean(false);
        List<SysApp> list = sysAppService.getlistBytrue();
        list.forEach(item -> {
            Dict dict = Dict.create();
            dict.put("code",item.getCode());
            dict.put("name",item.getName());
            //如果有默认激活的
            if (YesOrNotEnum.Y.getCode().equals(item.getActive())) {
                hasDefaultActive.set(true);
                dict.put("active", true);
                //将其放在第一个
                userAppDictList.add(0, dict);
            } else {
                dict.put("active", false);
                userAppDictList.add(dict);
            }
        });
        if (ObjectUtil.isNotEmpty(userAppDictList)) {
            //如果默认激活的系统没有，则第一个为默认激活的系统
            if (!hasDefaultActive.get()) {
                Dict dict = userAppDictList.get(0);
                dict.put("active", true);
            }
        }
        userInfo.setApps(userAppDictList);

        // 设置权限列表
        Set<String> permissions = new HashSet<>();
        roles.forEach(role -> {
            List<String> permissionsList = sysPermissionMapper.listMenusByRoleId(role).stream()
                    .filter(sysMenu -> StrUtil.isNotBlank(sysMenu.getPerms()))
                    .map(SysPermission::getPerms)
                    .collect(Collectors.toList());
            permissions.addAll(permissionsList);
        });
        userInfo.setPermissions(ArrayUtil.toArray(permissions, String.class));
        return userInfo;
    }


    /**
     * @param currentUserId 当前用ID
     * @param password      原密码
     * @param newPassword   新密码
     * @return true 更新成功 false 更新失败
     */
    @Override
    public boolean updatePassword(Long currentUserId, @NotBlank(message = "旧密码不能为空") String password, @NotBlank(message = "新密码不能为空") String newPassword) {
        SysUser userEntity = getById(currentUserId);
        /**
         * 新密码进行加密
         */
        newPassword = ENCODER.encode(newPassword);

        /**
         * 判断原有密码是否相同
         */
        if (!ENCODER.matches(password, userEntity.getPassword())) {
            throw new BizException("旧密码错误");
        }

        userEntity.setPassword(newPassword);
        return this.update(userEntity,
                new LambdaUpdateWrapper<SysUser>().eq(SysUser::getUserId, currentUserId));
    }


    /**
     * 新增用户信息
     *
     * @param user 用户信息
     * @return 保存标识
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveUser(UserDto user) {

        String value = Global.getConfig("sys.user.initPassword", "123456");
        user.setPassword(ENCODER.encode(value));
        baseMapper.insert(user);
        List<SysUserRole> userRoleList = Arrays.stream(user.getRoleIdList()).map(roleId -> {
            SysUserRole userRole = new SysUserRole();
            userRole.setUserId(user.getUserId());
            userRole.setRoleId(roleId);
            return userRole;
        }).collect(Collectors.toList());
        return sysUserRoleService.saveBatch(userRoleList);
    }


    /**
     * 更新用户信息
     *
     * @param user 用户信息
     * @return 成功表示
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateUserById(UserDto user) {
        this.updateById(user);
        sysUserRoleService.remove(Wrappers.<SysUserRole>update().lambda()
                .eq(SysUserRole::getUserId, user.getUserId()));
        List<SysUserRole> userRoleList = Arrays.stream(user.getRoleIdList()).distinct().map(roleId -> {
            SysUserRole userRole = new SysUserRole();
            userRole.setUserId(user.getUserId());
            userRole.setRoleId(roleId);
            return userRole;
        }).collect(Collectors.toList());
        return sysUserRoleService.saveBatch(userRoleList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteUserById(Long userId) {
        sysUserRoleService.remove(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userId));
        this.removeById(userId);
        return Boolean.TRUE;
    }


    /**
     * 用户下拉菜单
     *
     * @return 用户List
     */
    @Override
    public List<SysUser> dropDown() {
        return baseMapper.dropDown();
    }
}
